# -*- coding: utf-8 -*-
"""
积分系统模块 - 数据模型
"""

from django.db import models
from django.core.validators import MinValueValidator
from django.conf import settings
from django.utils import timezone
from datetime import date


class PointRecord(models.Model):
    """
    积分记录模型
    
    记录用户积分的所有变动，包括获得和消费
    """
    
    # 积分变动类型
    TYPE_CHOICES = [
        ('earn_register', '注册奖励'),
        ('earn_activity', '参与活动'),
        ('earn_checkin', '活动签到'),
        ('earn_comment', '发表评论'),
        ('earn_rating', '活动评分'),
        ('earn_invite', '邀请好友'),
        ('spend_exchange', '积分兑换'),
        ('spend_privilege', '特权使用'),
        ('admin_adjust', '管理员调整'),
    ]
    
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='point_records',
        verbose_name='用户'
    )
    
    points = models.IntegerField(
        verbose_name='积分变动',
        help_text='正数表示增加，负数表示减少'
    )
    
    type = models.CharField(
        max_length=20,
        choices=TYPE_CHOICES,
        verbose_name='变动类型'
    )
    
    description = models.CharField(
        max_length=200,
        blank=True,
        verbose_name='描述',
        help_text='积分变动的详细说明'
    )
    
    # 关联对象（根据类型不同，可能关联活动、商品等）
    related_activity = models.ForeignKey(
        'activities.Activity',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='point_records',
        verbose_name='关联活动'
    )
    
    related_product = models.ForeignKey(
        'PointProduct',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='point_records',
        verbose_name='关联商品'
    )
    
    # 变动后的余额
    balance_after = models.IntegerField(
        verbose_name='变动后余额',
        help_text='本次变动后的积分余额'
    )
    
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='记录时间'
    )
    
    class Meta:
        db_table = 'point_records'
        verbose_name = '积分记录'
        verbose_name_plural = '积分记录'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', '-created_at']),
        ]
    
    def __str__(self):
        return f"{self.user.username} {self.get_type_display()} {self.points}积分"


class PointProduct(models.Model):
    """
    积分商品模型
    
    积分商城中可兑换的商品
    """
    
    # 商品类型
    TYPE_CHOICES = [
        ('voucher', '优惠券'),
        ('privilege', '平台特权'),
        ('physical', '实物奖品'),
        ('virtual', '虚拟物品'),
    ]
    
    # 商品状态
    STATUS_CHOICES = [
        ('available', '可兑换'),
        ('soldout', '已兑完'),
        ('offline', '已下架'),
    ]
    
    name = models.CharField(
        max_length=100,
        verbose_name='商品名称'
    )
    
    description = models.TextField(
        verbose_name='商品描述'
    )
    
    image = models.ImageField(
        upload_to='products/%Y/%m/',
        blank=True,
        null=True,
        verbose_name='商品图片',
        help_text='商品图片（自动存储到MinIO云存储）'
    )
    
    type = models.CharField(
        max_length=20,
        choices=TYPE_CHOICES,
        verbose_name='商品类型'
    )
    
    # 所需积分
    points_required = models.IntegerField(
        validators=[MinValueValidator(0)],
        verbose_name='所需积分'
    )
    
    # 库存
    stock = models.IntegerField(
        default=0,
        validators=[MinValueValidator(0)],
        verbose_name='库存数量'
    )
    
    # 已兑换数量
    exchange_count = models.IntegerField(
        default=0,
        verbose_name='兑换数量'
    )
    
    # 每人限兑数量（0表示不限制）
    limit_per_user = models.IntegerField(
        default=0,
        validators=[MinValueValidator(0)],
        verbose_name='每人限兑',
        help_text='每人限制兑换数量，0表示不限制'
    )
    
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='available',
        verbose_name='商品状态'
    )
    
    # 排序权重
    sort_order = models.IntegerField(
        default=0,
        verbose_name='排序',
        help_text='排序权重，数字越大越靠前'
    )
    
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='创建时间'
    )
    
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='更新时间'
    )
    
    class Meta:
        db_table = 'point_products'
        verbose_name = '积分商品'
        verbose_name_plural = '积分商品'
        ordering = ['-sort_order', '-created_at']
    
    def __str__(self):
        return f"{self.name} ({self.points_required}积分)"


class PointExchange(models.Model):
    """
    积分兑换记录模型
    
    记录用户使用积分兑换商品的记录
    """
    
    # 兑换状态
    STATUS_CHOICES = [
        ('pending', '待发放'),
        ('processing', '处理中'),
        ('completed', '已完成'),
        ('cancelled', '已取消'),
    ]
    
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='exchanges',
        verbose_name='用户'
    )
    
    product = models.ForeignKey(
        PointProduct,
        on_delete=models.CASCADE,
        related_name='exchanges',
        verbose_name='商品'
    )
    
    points_spent = models.IntegerField(
        verbose_name='消耗积分'
    )
    
    quantity = models.IntegerField(
        default=1,
        validators=[MinValueValidator(1)],
        verbose_name='兑换数量'
    )
    
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='pending',
        verbose_name='兑换状态'
    )
    
    # 收货信息（实物商品需要）
    receiver_name = models.CharField(
        max_length=50,
        blank=True,
        verbose_name='收货人'
    )
    
    receiver_phone = models.CharField(
        max_length=11,
        blank=True,
        verbose_name='联系电话'
    )
    
    receiver_address = models.CharField(
        max_length=300,
        blank=True,
        verbose_name='收货地址'
    )
    
    # 物流信息
    tracking_number = models.CharField(
        max_length=100,
        blank=True,
        verbose_name='物流单号'
    )
    
    remark = models.TextField(
        blank=True,
        verbose_name='备注'
    )
    
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='兑换时间'
    )
    
    completed_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='完成时间'
    )
    
    class Meta:
        db_table = 'point_exchanges'
        verbose_name = '积分兑换'
        verbose_name_plural = '积分兑换'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', '-created_at']),
            models.Index(fields=['status']),
        ]
    
    def __str__(self):
        return f"{self.user.username} 兑换 {self.product.name}"


class DailyCheckin(models.Model):
    """
    每日签到模型
    
    记录用户每日签到情况和连续签到天数
    """
    
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='checkins',
        verbose_name='用户'
    )
    
    checkin_date = models.DateField(
        verbose_name='签到日期',
        help_text='签到的日期'
    )
    
    points_earned = models.IntegerField(
        default=5,
        verbose_name='获得积分',
        help_text='本次签到获得的积分'
    )
    
    consecutive_days = models.IntegerField(
        default=1,
        verbose_name='连续签到天数',
        help_text='截至本次的连续签到天数'
    )
    
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='签到时间'
    )
    
    class Meta:
        db_table = 'daily_checkins'
        verbose_name = '每日签到'
        verbose_name_plural = '每日签到'
        unique_together = ('user', 'checkin_date')
        ordering = ['-checkin_date']
        indexes = [
            models.Index(fields=['user', '-checkin_date']),
        ]
    
    def __str__(self):
        return f"{self.user.username} - {self.checkin_date} (连续{self.consecutive_days}天)"
    
    @classmethod
    def get_user_consecutive_days(cls, user):
        """
        获取用户当前连续签到天数
        """
        today = date.today()
        yesterday = date.today() - timezone.timedelta(days=1)
        
        # 检查今天是否已签到
        today_checkin = cls.objects.filter(user=user, checkin_date=today).first()
        if today_checkin:
            return today_checkin.consecutive_days
        
        # 检查昨天的签到记录
        yesterday_checkin = cls.objects.filter(user=user, checkin_date=yesterday).first()
        if yesterday_checkin:
            return yesterday_checkin.consecutive_days
        
        return 0
    
    @classmethod
    def has_checked_in_today(cls, user):
        """
        检查用户今天是否已签到
        """
        today = date.today()
        return cls.objects.filter(user=user, checkin_date=today).exists()
